import com.lbi.animation.animator.Animator;
import com.lbi.animation.animator.Transition;
import com.lbi.animation.util.Engine;
import com.lbi.debug.Log;
import com.lbi.debug.LogType;
import com.lbi.framework.mvc.view.ViewBase;

import asunit.framework.TestCase;

import flash.geom.Point;
import framework.view.DummyView;

/**
	LBi Useful ActionScript 2 Library     Copyright (C) 2007 LBi / Michael Forrest      This library is free software; you can redistribute it and/or     modify it under the terms of the GNU Lesser General Public     License as published by the Free Software Foundation; either     version 2.1 of the License, or (at your option) any later version.      This library is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU     Lesser General Public License for more details.      You should have received a copy of the GNU Lesser General Public     License along with this library; if not, write to the Free Software     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
 */
class framework.view.AnimatorTest extends TestCase {
	private var className : String = "AnimatorTest";

	private var animated : ViewBase; // just so we don't get warnings on _alpha :)

	private var animator : Animator;

	private var MORE_FRAMES_THAN_WILL_BE_IN_A_DEFAULT : Number = 100;

	private var START_VALUE : Number = 100;
	
	public function AnimatorTest(testMethod : String) {
		super(testMethod);
	}
	private function setUp() :Void{
		animated = DummyView.create(_root,_root.getNextHighestDepth());
		animated._alpha = START_VALUE;
		animator = new Animator(animated);
		animator.registerTransition("_alpha"); 
	}
	private function tearDown() :Void{
		delete animated;
		delete animator;
	}
	private function testNormalProperties() : Void{
		var target_alpha : Number = START_VALUE - 100;
		animator._alpha = target_alpha; // this is what should trigger an animation.
		Engine.advanceFrames(1); // force a frame of the animation
		assertTrue("animation should have started:" +
					"_alpha = "+ animated._alpha ,
					animated._alpha>0 && animated._alpha < 100);
		Engine.advanceFrames(MORE_FRAMES_THAN_WILL_BE_IN_A_DEFAULT);
		assertEquals("should continue to the final value",
					target_alpha, animated._alpha);
	}
	private function testDirectAccessDoesNotBreak() :Void{
		animator._alpha = 0; // start animation
		Engine.advanceFrames(3);
		var direct_target : Number = 100;
		animated._alpha = 100; // directly access property on animated
		Engine.advanceFrames(MORE_FRAMES_THAN_WILL_BE_IN_A_DEFAULT);
		assertEquals(direct_target,animated._alpha);
	}
	/**
	 * it would be better to throw an error if an unregistered property is accessed
	 * but for now... I guess it's just gonna have to silently fail.
	private function testForcesRegistrationOfSpecialProperties() :Void {
		Log.clear();
		animator.special_property = 230;
		assertEquals(LogType.ERROR,Log.getLastMessageType());
		Log.clear();
		animator.registerProperty("special_property");
		animator.special_property = 230;
		assertNotNull(animated.special_property);
	}
	 */
	public function testDirectAccessOfAccessorPropertiesDoesNotBreak() :Void{
		animator.registerTransition("_alpha"); // special case if it's an actual MovieClip
		animator._alpha = 0;
		Engine.advanceFrames(2);
		var direct_target : Number = 200;
		animated._alpha = direct_target;
		Engine.advanceFrames(MORE_FRAMES_THAN_WILL_BE_IN_A_DEFAULT);
		assertEquals(direct_target,animated._alpha);
	}


	public function testGivesWarningIfNoDefaultValueForAccessor() :Void{
		Log.clear();
		animator.registerTransition("no_default");
		assertEquals("animator should warn if no default accessor value", 
					LogType.WARNING,Log.getLastMessageType());	
	}
	public function testSetPosition() :Void{
		assertEquals("animation should start from _x=0",0,animated._x);
		assertEquals("animation should have a _y value too",0,animated._y);
		var target:Number = 100;
		animator.setPosition(new Point(target,0));
		assertEquals("setPosition should not be instant",0,animated._x);
		Engine.advanceFrames(MORE_FRAMES_THAN_WILL_BE_IN_A_DEFAULT);
		assertEquals("after lots of frames we should be at the next position",target,animated._x);
	}
	public function testSetPropertiesWithChaining() :Void{
		assertNotUndefined(animator.change("_alpha"));
		assertEquals("_alpha",animator.change("_alpha").property);
		var frames : Number = MORE_FRAMES_THAN_WILL_BE_IN_A_DEFAULT;
		assertEquals("checking frame count can be chained through",
						frames,
						animator.change("_alpha").setFrames(frames).frames);
		var easing : Function = function(v:Number) {return v;};
		assertSame("easing function should be passed through",
						easing,
						animator.change("_alpha").setEasing(easing).easing);
	}
	public function testCanSetPositionProperties() :Void{
		var t : Transition = animator.change(ViewBase.POSITION);
		assertEquals("position animator should be found - found "+t+" with property=" + t.property,
						ViewBase.POSITION,t.property);
	}

}